package de.hypoport.einarbeitung.scrumspirit.persistence.genericdao.jpa2;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.LockModeType;
import javax.persistence.Query;

import de.hypoport.einarbeitung.scrumspirit.persistence.genericdao.Dao;

/**
 * Base interface for JPA DAOs. To use, extend it in DAO interfaces.
 * 
 * @param <K>
 *            The primary key class of the entity, e.g. Long.
 * @param <E>
 *            The entity class the DAO persists, e.g. Person.
 */
public interface Jpa2Dao<K, E> extends Dao<K, E> {
    /**
	 * Find an entity by its id, optionally throwing an exception if not found
	 * (this prevents <code>NullPointerException</code>s from occurring later),
	 * and optionally locking the found entity.
	 * 
	 * @param id
	 *            The id (primary key) of the entity to find.
	 * @param lockMode
	 *            Lock the entity in the persistence context for the specified
	 *            lockMode, or null for no locking.
	 * @param exceptionIfNotFound
	 *            true to throw an exception if entity not found.
	 * @return The entity for the specified id, null when entity not found or
	 *         exception thrown based on the param.
	 * @throws EntityNotFoundException
	 *             When entity not found and exceptionIfNotFound is true.
	 */
    E findById(K id, LockModeType lockMode, boolean exceptionIfNotFound);

    /**
	 * Run the specified query, using getSingleResult(), expecting a single
	 * entity result and returning null if not found.
	 * 
	 * @param q
	 *            The query to run getSingleResult() on.
	 * @return The single entity found from the query execution or null if not
	 *         found.
	 */
    E runQueryWithSingleResult(Query q);

    /**
	 * Run the specified query, using getSingleResult(), expecting a single
	 * entity result and returning null if not found.
	 * 
	 * @param q
	 *            The query to run getSingleResult() on.
	 * @param lockMode
	 *            Lock the entity in the persistence context for the specified
	 *            lockMode, or null for no locking.
	 * @param exceptionIfNotFound
	 *            true to throw an exception if entity not found.
	 * @return The single entity found from the query execution.
	 */
    E runQueryWithSingleResult(Query q, LockModeType lockMode,
            boolean exceptionIfNotFound);

    /**
	 * Get the EntityManager used for operations.
	 * 
	 * @return The EntityManager used for operations.
	 */
    EntityManager getEntityManager();

    /**
	 * Set the EntityManager used for operations.
	 * 
	 * @param entityManager
	 *            The entity manager to use for operations.
	 */
    void setEntityManager(EntityManager entityManager);

	/**
	 * Set to true if you have to use transactions
	 * 
	 * @param needTransaction
	 */
	void setNeedTransaction(boolean needTransaction);

	boolean isNeedTransaction();
}
